package org.jeecg.modules.simulator.rooter;

import lombok.Getter;
import lombok.Setter;
import org.jeecg.modules.simulator.jsonot.NumPeopEnStationApiInfo;
import org.jeecg.modules.simulator.jsonot.PsgStationDistributionInfo;
import org.jeecg.modules.simulator.model.line.Line;
import org.jeecg.modules.simulator.model.line.station.station.Station;
import org.jeecg.modules.simulator.util.TimeUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: simulator-b20240918
 * @description: 数据加载者
 * @author: renzhg
 * @create: 2025-01-09 08:55
 **/
public class DataManagerRooter {


    Map<String, TrainManager> trainManagerMap = new HashMap<>();

    @Getter
    @Setter
    DataLoadRooter dataLoadRooter;
    @Getter
    @Setter
    String netStartTrainTime;
    @Getter
    @Setter
    String sceneCode;
    @Getter
    @Setter
    NetRooter netRooter;


    DataCalculateRooter dataCalculateRooter;


    //    Map<String, List<PsgStationDistributionInfo>> psgStationDistributionInfoMap = new HashMap<>();
    @Getter
    @Setter
    Map<String, Map<String, NumPeopEnStationApiInfo>> numPeopEnStationApiInfoMap = new HashMap<>();


    //计算进站量将来的数据
    public Map<String, NumPeopEnStationApiInfo> calculateInputFuture(String now) {
        return dataCalculateRooter.calculateInputFutureFiveMin(now);
    }


    /**
     * @description: 这个比较难算，
     * <p>
     * 每个进站点对应路径所需的预估计时间
     * 1、所有站的出站时间
     * 2、通过出站时间反推是否有列车到达
     * 3、计算到达列车在这个站的下车人数-----
     * a、列车本身自有人数
     * b、OD路径小于5分钟的人数（两站以内）还有换乘路径小于5分钟的（换乘节点小于两站）--这个计算麻烦
     * 数据准备：
     * 1、准备所有站点出站时间的集合
     * 2、列车在站时间段包含时间点(（需求时间点-站内走行时间）得到的时间点)的
     * 3、到达列车计算统计这个时间点的人数
     * <p>
     * 路径节点
     * @author: renzhg
     * @date: 2025/1/10 10:11
     **/
    public void calculateOutputFuture(String now) {


    }


//    public void init() {
//        RooterInitializer rooterInitializer = initData();
//        initAfterSetData(rooterInitializer);
//        setTrainListenerParam();
//
//    }

    public void initDataSet(){
        netRooter.getLineRooterMap().forEach((k, v) -> {
            v.getLine().setSceneCode(sceneCode);
            v.getLine().setSceneCode(sceneCode);
//            v.getLine().setT80RouteHisMap(netRooter.t80RouteHisMap);
            v.getLine().setStationNetMap(netRooter.stationMap);
            v.getLine().setTransferStationMap(netRooter.transferStationMap);
        });

        netRooter.linesStationMap.forEach((k, v) -> {
            // 从 lineAllMap 中使用键获取 Line 对象
            Line line = netRooter.lineAllMap.get(k);
            // 初始化 LineRooter 对象// 为当前线路创建一个站点 ID 到 Station 对象的映���
            Map<String, Station> stationLineMap = v.stream().collect(Collectors.toMap(Station::getId, station -> station));
            // 为当前线路设置站点映射
            line.setStationMap(stationLineMap);
            // 分配停车场及
        });
    }
//    public void initTrain() {
////        RooterInitializer rooterInitializer = initTrainData();
////        initAfterSetData(rooterInitializer);
////        setTrainListenerParam();
//
//    }



    public RooterInitializer initRooterInitializer() {
        // 生成一个RooterInitializer实例
        RooterInitializer rooterInitializer = newData2RooterInitializer();
        // 把站点对象分配给各个线路(列车生成-》车辆段;列车时刻表-》线路)
        // 为每个线路路由器设置各种映射
        newTrainAndOrbit2Line(rooterInitializer);
//        netRooter.lineRooterMap.forEach((k, v) -> {
//            v.getLine().setSceneCode(sceneCode);
////            v.getLine().setT80RouteHisMap(netRooter.t80RouteHisMap);
//            v.getLine().setStationNetMap(netRooter.stationMap);
//            v.getLine().setTransferStationMap(netRooter.transferStationMap);
//        });
        rooterInitializer.initTrainTableBizData();//列车时刻表生成列车动作列表,将人员分配到列车上、以及设置站点和换乘站数据。

        return rooterInitializer;

    }

//    public RooterInitializer initData() {
//        // 生成一个RooterInitializer实例
//        RooterInitializer rooterInitializer = generateRooterInitializer();
//        // 把站点对象分配给各个线路(列车生成-》车辆段;列车时刻表-》线路)
//        // 为每个线路路由器设置各种映射
//        newTrainAndOrbit2Line(rooterInitializer);
//        netRooter.lineRooterMap.forEach((k, v) -> {
//            v.getLine().setSceneCode(sceneCode);
//            v.getLine().setT80RouteHisMap(netRooter.t80RouteHisMap);
//            v.getLine().setStationNetMap(netRooter.stationMap);
//            v.getLine().setTransferStationMap(netRooter.transferStationMap);
//        });
//
//
//
//
//        return rooterInitializer;
//    }

    public RooterInitializer newData2RooterInitializer() {
        RooterInitializer rooterInitializer = new RooterInitializer();
        rooterInitializer.setSceneCode(sceneCode);
        rooterInitializer.setLineRooterMap(netRooter.lineRooterMap);
        rooterInitializer.setLineAllMap(netRooter.lineAllMap);
        rooterInitializer.setStationMap(netRooter.stationMap);
        rooterInitializer.setTransferStationMap(netRooter.transferStationMap);
        rooterInitializer.setPersonPathMap(netRooter.personPathMap);
        rooterInitializer.setPersonTrainMapByLine(netRooter.personTrainMapByLine);
        rooterInitializer.setLinesStationMap(netRooter.linesStationMap);
        rooterInitializer.setStationNameMap(netRooter.stationNameMap);
        rooterInitializer.setParkerMap(netRooter.parkerMap);
        rooterInitializer.setTrainPlanTableMapByLine(netRooter.trainPlanTableMapByLine);
        rooterInitializer.setPsgStationDistributionInfoMap(netRooter.psgStationDistributionInfoMap);
        rooterInitializer.setOdProbabilityApiInfoMap(netRooter.odProbabilityApiInfoMap);
        rooterInitializer.setNumPeopEnStationApiInfoMap(netRooter.numPeopEnStationApiInfoMap);
//        rooterInitializer.initSceneCode2Line();
//        rooterInitializer.initLineStationMap();
        return rooterInitializer;


    }


    /**
     * @description: 组装线网中个各个需要的参数，分配车辆给车辆段
     * 这个方法重要
     * 1、创建新车--->各个车辆段
     * 2、生成一个名字的站点字典
     * 3、生成一个id的站点字典
     * 4、生成上下行轨道轨道
     * 5、生成停车场--停车场中装配了列车数据
     * 6、组装到线路数据中
     * 7、分配路径到每个站点
     * 8、分配轨道到车站
     * @author: renzhg
     * @date: 2024/11/16 10:09
     **/
    private void newTrainAndOrbit2Line(RooterInitializer rooterInitializer) {

        rooterInitializer.assemblyAction();//组装线路lineRooter
        // 从rooterInitializer中设置线路映射
        netRooter.lineMap = rooterInitializer.getLineMap();



    }


    /**
     * @description: 初始化后，设置数据
     * @author: renzhg
     * @date: 2024/11/30 12:12
     **/
    public void initAfterSetData(RooterInitializer rooterInitializer) {
        // 获取未分配的地铁列车映射
        netRooter.metroTrainNoAssigeMap = rooterInitializer.getMetroTrainNoAssigeMap();
        // 初始化每条线路的首班车时间
        netStartTrainTime = rooterInitializer.initEveryLineFirstTrainStartTime();
        netRooter.netStartTrainTime = netStartTrainTime;
        rootPublicsherAssign();
        // 确保网络首班车时间不早于04:00:00
        if (TimeUtil.compareStrTimes("04:00:00", netRooter.netStartTrainTime).equals("2")) {
            netRooter.netStartTrainTime = "04:00:00";

        }
    }


    //网络打印配置
    private void rootPublicsherAssign() {
        // 为根发布者设置线路路由器映射
        netRooter.rootPublisher.setLineRooterMap(netRooter.lineRooterMap);
        // 为每个线路路由器配置线路信息发布者
        netRooter.lineRooterMap.forEach((k, v) -> {
            v.lineInfoPublisher.setLine(v.line);
            v.lineInfoPublisher.setSceneCode(this.sceneCode);
            v.lineInfoPublisher.setTrainManager(v.trainManager);
            v.lineInfoPublisher.setStationInThisLineMap(v.getStationInThisLineMap());
            v.lineInfoPublisher.setParkerMap(v.parkerMap);
//            v.reacorder.setSceneCode(this.sceneCode);
//            v.reacorder.setStationInThisLineMap(v.getStationInThisLineMap());
        });
    }

    //    按停车场分配的车辆，把车辆集合放入的停车场的集合中
    public void setTrainListenerParam() {
        netRooter.offTrainNumRangeMap = netRooter.simulatorParam.getOffTrainNumRangeMap();
        netRooter.trainListener.setOffTrainNumRangeMap(netRooter.offTrainNumRangeMap);
        netRooter.trainListener.setParkersMap(netRooter.parkersMap);
        netRooter.trainListener.setStationMap(netRooter.stationMap);
        netRooter.trainListener.setLineRooterMap(netRooter.lineRooterMap);
        netRooter.trainListener.setTransferNameStationMap(netRooter.transferNameStationMap);
        netRooter.trainListener.setStationNameMap(netRooter.stationLineStaionNameMap);
        netRooter.trainListener.setLineMap(netRooter.lineMap);
    }

}
